package com.lmk.basic.service.Impl;

import com.lmk.basic.dto.SmsCodeDto;
import com.lmk.basic.exception.BusinessException;
import com.lmk.basic.service.IVerifyCodeService;
import com.lmk.basic.util.StrUtils;
import com.lmk.basic.util.VerifyCodeUtils;
import com.lmk.user.domain.User;
import com.lmk.user.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Override
    public String image(String key) {
        //生成code
        String complexRandomString = StrUtils.getComplexRandomString(4);
        //保存到redis
        redisTemplate.opsForValue().set(key, complexRandomString, 5, TimeUnit.MINUTES);
        //转为base64
        String base64ImageCode = VerifyCodeUtils.verifyCode(115, 40, complexRandomString);
        return base64ImageCode;

    }

    @Override
    public void sendSmsCode(SmsCodeDto smsCodeDto) {
        // 1.空值校验
        String phone = smsCodeDto.getPhone();// 电话号码
        String imageCode = smsCodeDto.getImageCode();// 图形验证码
        String imageCodeKey = smsCodeDto.getImageCodeKey();
        if (StringUtils.isEmpty(phone)) {
            throw new BusinessException("手机号不能为空");
        }
        if (StringUtils.isEmpty(imageCode)) {
            throw new BusinessException("验证码不能为空");
        }
        if (StringUtils.isEmpty(imageCodeKey)) {
            throw new BusinessException("请重新获取验证码");
        }

        // 2.验证图像验证码是否过期
        Object imgObj = redisTemplate.opsForValue().get(imageCodeKey);
        if (imgObj == null) {
            //2.1.图片验证码是否过期
            throw new BusinessException("图形验证码已过期");
        }
        if (!imgObj.toString().equalsIgnoreCase(imageCode)) {
            //2.2.图片验证码是否正确
            throw new BusinessException("图形验证码错误");
        }
        //3.校验 - 手机号是否被注册 - 查询t_user表
        User user = userMapper.loadByPhone(phone);
        if (user != null) {
            throw new BusinessException("改手机号已被注册,请直接登录");
        }
        //4.判断原来的验证码是否有效【3分钟过期 - redis】
        Object codeObj = redisTemplate.opsForValue().get("register" + phone);
        // 如果过期或没有，就生成
        String smsCode = null;
        if (codeObj == null) {
            //如果第一次发送，redis里面没有验证码，就随机生成一个六位数的手机验证码
            smsCode = StrUtils.getRandomString(4);
        } else {
            //以前的时间
            String oldTimeTemp = codeObj.toString().split(":")[1];
            //转化为long类型
            long oldTime = Long.parseLong(oldTimeTemp);

            //获取当前时间戳
            long nowTime = System.currentTimeMillis();
            //设置发送短信的重复发送需要超过一分钟
            if ((nowTime - oldTime) < 1 * 60 * 1000) {
                //放置用户刷新页面，抛繁忙异常
                throw new BusinessException("操作频繁，请稍后再试");
            } else {
                //如果曹操过了一分钟，就获取到之前的验证码，重新发送一次
                smsCode = codeObj.toString().split(":")[0];
            }
        }
        //5.将验证码保存到redis 重新设置有效期，放置还剩一秒过期这种情况
        redisTemplate.opsForValue().set("register" + phone,
                smsCode + ":" + System.currentTimeMillis(), 3, TimeUnit.MINUTES);
        //6.调用短信接口发送短信
        /*String context = "你的验证码为：" + smsCode + "，请在3分钟之内使用!";
        SmsUtils.sendSms(phone,context);*/
        System.out.println("你的验证码为：" + smsCode + "，请在3分钟之内使用!");

    }

    @Override
    public void binderSmsCode(SmsCodeDto smsCodeDto) {
        String phone = smsCodeDto.getPhone();
        //1.校验 - 空值校验
        if (StringUtils.isEmpty(phone)) {
            throw new BusinessException("手机号码不能为空!!!");
        }
        //4.判断原来的验证码是否有效【3分钟过期 - redis】
        Object codeObj = redisTemplate.opsForValue().get("binder:" + phone);
        // 如果过期或没有，就生成
        String smsCode = null;
        if (codeObj == null) {
            //如果第一次发送，redis里面没有验证码，就随机生成一个六位数的手机验证码
            smsCode = StrUtils.getRandomString(4);
        } else {
            //以前的时间
            String oldTimeTemp = codeObj.toString().split(":")[1];
            //转化为long类型
            long oldTime = Long.parseLong(oldTimeTemp);

            //获取当前时间戳
            long nowTime = System.currentTimeMillis();
            //设置发送短信的重复发送需要超过一分钟
            if ((nowTime - oldTime) < 1 * 60 * 1000) {
                //放置用户刷新页面，抛繁忙异常
                throw new BusinessException("操作频繁，请稍后再试");
            } else {
                //如果曹操过了一分钟，就获取到之前的验证码，重新发送一次
                smsCode = codeObj.toString().split(":")[0];
            }
        }
        //5.将验证码保存到redis 重新设置有效期，放置还剩一秒过期这种情况
        redisTemplate.opsForValue().set("binder:" + phone,
                smsCode + ":" + System.currentTimeMillis(), 3, TimeUnit.MINUTES);
        //6.调用短信接口发送短信
        /*String context = "你的验证码为：" + smsCode + "，请在3分钟之内使用!";
        SmsUtils.sendSms(phone,context);*/
        System.out.println("你的验证码为：" + smsCode + "，请在3分钟之内使用!");
    }
}
